package eshttp

import (
	"fmt"
	"net/http"
	"strconv"
	"strings"

	"gitee.com/les49/esgo/errors"
	"github.com/zeromicro/go-zero/rest/httpx"
)

type DownLoadReq struct {
	File string `path:"file"`
}

func Download(w http.ResponseWriter, r *http.Request, body []byte, filename string) {
	var rangeStart, rangeEnd int64

	w.Header().Add("Accept-ranges", "bytes")
	w.Header().Add("Content-Type", "application/octet-stream")
	w.Header().Set("Content-Disposition", "attachment; filename="+filename)
	if headerRange := r.Header.Get("Range"); len(headerRange) > 0 {
		if strings.Contains(headerRange, "bytes=") && strings.Contains(headerRange, "-") {
			fmt.Sscanf(headerRange, "bytes=%d-%d", &rangeStart, &rangeEnd)
			if rangeEnd == 0 {
				rangeEnd = int64(len(body)) - 1
			}
			if rangeStart > rangeEnd || rangeStart < 0 || rangeEnd < 0 || rangeEnd >= int64(len(body)) {
				w.WriteHeader(http.StatusRequestedRangeNotSatisfiable)
				httpx.Error(w, errors.FileReadException)
				return
			}
			w.Header().Set("Content-Length", strconv.FormatInt(rangeEnd-rangeStart+1, 10))
			w.Header().Add("Content-Range", fmt.Sprintf("bytes %v-%v/%v", rangeStart, rangeEnd, int64(len(body))))
			w.WriteHeader(http.StatusPartialContent)
		} else {
			w.WriteHeader(http.StatusBadRequest)
			httpx.Error(w, errors.FileReadException)
			return
		}
	} else {
		w.Header().Set("Content-Length", strconv.FormatInt(int64(len(body)), 10))
		rangeStart = 0
		rangeEnd = int64(len(body)) - 1
	}

	var packageSize int64 = 512
	for {

		if ((rangeEnd - rangeStart) + 1) < packageSize {
			packageSize = (rangeEnd - rangeStart) + 1
		}
		if _, err := w.Write(body[rangeStart : rangeStart+packageSize]); err != nil {
			httpx.Error(w, errors.FileWriteException)
			return
		}

		rangeStart = rangeStart + packageSize
		if rangeStart >= rangeEnd {
			return
		}
	}
}
